package com.pro_one.controller;

import com.pro_one.constant.MessageConstant;
import com.pro_one.entity.Result;
import com.pro_one.service.MemberService;
import com.pro_one.service.OrderService;
import com.pro_one.service.ReportService;
import com.pro_one.service.SetmealService;
import com.pro_one.util.DateUtils;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletContext;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@RestController
@RequestMapping("/report")
public class ReportController {
    @Reference
    private MemberService memberService;
    @Reference
    private SetmealService setmealService;
    @Reference
    private ReportService reportService;
    @Reference
    private OrderService orderService;


    @RequestMapping("/getOrderReport")
    public Result getOrderReport(@RequestBody String[] value1) throws Exception {
        Map<String, Object> map = new HashMap<>();
        //开始日期
        String startTime = value1[0];
        //结束日期
        String endTime = value1[1];
        //日期格式化
        Date startDate = DateUtils.parseString2Date(startTime);
        Date endDate = DateUtils.parseString2Date(endTime);

        //定义日期实例
        Calendar calendar = Calendar.getInstance();
        //将日期放入日历
        //calendar.setTime(startDate);
        //每日
        List<String> orderDay = new ArrayList<>();

        //计算两个日期的相隔天数
        //设置为开始时间
        calendar.setTime(startDate);
        //获取时间的毫秒值
        long time1 = calendar.getTimeInMillis();
        calendar.setTime(endDate);
        long time2 = calendar.getTimeInMillis();
        //获取有多少天
        long days = (time2 - time1) / (1000 * 3600 * 24);
        calendar.setTime(startDate);

        for (long i = 0; i <= days; i++) {
            //获取当前日期
            Date date1 = calendar.getTime();
            //日期格式化
            orderDay.add(new SimpleDateFormat("yyyy-MM-dd").format(date1));
            //日期向后加一天
            calendar.add(Calendar.DATE, 1);
        }
        map.put("orderDay", orderDay);

        //每日预约人数
        List<Integer> orderCount = orderService.findOrderCount(orderDay);
        map.put("orderCount",orderCount);
        //每日到诊人数
        List<Integer> orderGetCount = orderService.orderGetCount(orderDay);
        map.put("orderGetCount",orderGetCount);
        return new Result(true, "数据统计成功", map);
    }




    //收益百分比
    @RequestMapping("/getMoneyReport")
    public Result getMoneyReport(@RequestBody String[] value1){
        Map<String, Object> map =new HashMap<>();

        //开始日期
        String startTime = value1[0];
        //结束日期
        String endTime = value1[1];

        //日期格式化
        Date startDate = null;
        Date endDate = null;
        try {
            startDate = DateUtils.parseString2Date(startTime);
            endDate = DateUtils.parseString2Date(endTime);
        } catch (Exception e) {
            e.printStackTrace();
        }

        //定义日期实例
        Calendar calendar = Calendar.getInstance();
        //将日期放入日历
        //calendar.setTime(startDate);
        //每日
        List<String> orderDay = new ArrayList<>();

        //计算两个日期的相隔天数
        //设置为开始时间
        calendar.setTime(startDate);
        //获取时间的毫秒值
        long time1 = calendar.getTimeInMillis();
        calendar.setTime(endDate);
        long time2 = calendar.getTimeInMillis();
        //获取有多少天
        long days = (time2 - time1) / (1000 * 3600 * 24);
        calendar.setTime(startDate);

        for (long i = 0; i <= days; i++) {
            //获取当前日期
            Date date1 = calendar.getTime();
            //日期格式化
            orderDay.add(new SimpleDateFormat("yyyy-MM-dd").format(date1));
            //日期向后加一天
            calendar.add(Calendar.DATE, 1);
        }
        map.put("orderDay", orderDay);


        //各套餐收入占比
        List<Map<String, Object>>  setmealMoneyCount = setmealService.findMoneyCountBySetmeal(orderDay);



        if(setmealMoneyCount == null){
            return new Result(false,"错误");
        }
        //收入和名称集合
        map.put("setmealMoneyCount",setmealMoneyCount);
        //各套餐收入名称
        List<String> setmealMoneyNames = new ArrayList<>();

        for (Map<String, Object> stringObjectMap : setmealMoneyCount) {
            //获取套餐名称
            String name = (String) stringObjectMap.get("name");
            setmealMoneyNames.add(name);
        }
        //套餐名称
        map.put("setmealMoneyNames",setmealMoneyNames);
        return new Result(true,"套餐收入比例图查询成功",map);
    }






    /**
     * 页面展示会员增长折线图
     *
     * @return
     */
    @RequestMapping("/getMemberReport")
    @PreAuthorize("hasAuthority('REPORT_VIEW')")
    public Result getMemberReport() {
        try {
            Map map = memberService.getMemberReport();
            return new Result(true, MessageConstant.GET_MEMBER_NUMBER_REPORT_SUCCESS, map);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(false, MessageConstant.GET_MEMBER_NUMBER_REPORT_FAIL);
        }
    }

    /**
     * 展示页面套餐数据的饼图
     *
     * @return
     */
    @RequestMapping("/getSetmealReport")
    public Result getSetmealReport() {
        try {
            Map map = setmealService.getSetmealReport();
            return new Result(true, MessageConstant.GET_SETMEAL_COUNT_REPORT_SUCCESS, map);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(false, MessageConstant.GET_SETMEAL_COUNT_REPORT_FAIL);
        }
    }

    /**
     * 页面展示运营数据
     *
     * @return
     */
    @RequestMapping("/getBusinessReportData")
    public Result getBusinessReportData() {
        try {
            Map<String, Object> map = reportService.getBusinessReportData();
            return new Result(true, MessageConstant.GET_BUSINESS_REPORT_SUCCESS, map);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(false, MessageConstant.GET_BUSINESS_REPORT_FAIL);
        }
    }

    /**
     * 导出excel
     *
     * @param request
     * @param response
     */
    @RequestMapping("/exportBusinessReport")
    public void exportBusinessReport(HttpServletRequest request, HttpServletResponse response) {
        XSSFWorkbook workbook = null;
        ServletOutputStream os = null;
        try {
            Map<String, Object> reportData = reportService.getBusinessReportData();
            String reportDate = (String) reportData.get("reportDate");
            Integer todayNewMember = (Integer) reportData.get("todayNewMember");
            Integer totalMember = (Integer) reportData.get("totalMember");
            Integer thisWeekNewMember = (Integer) reportData.get("thisWeekNewMember");
            Integer thisMonthNewMember = (Integer) reportData.get("thisMonthNewMember");
            Integer todayOrderNumber = (Integer) reportData.get("todayOrderNumber");
            Integer todayVisitsNumber = (Integer) reportData.get("todayVisitsNumber");
            Integer thisWeekOrderNumber = (Integer) reportData.get("thisWeekOrderNumber");
            Integer thisWeekVisitsNumber = (Integer) reportData.get("thisWeekVisitsNumber");
            Integer thisMonthOrderNumber = (Integer) reportData.get("thisMonthOrderNumber");
            Integer thisMonthVisitsNumber = (Integer) reportData.get("thisMonthVisitsNumber");
            List<Map> hotSetmeal = (List<Map>) reportData.get("hotSetmeal");
            //获取服务器端绝对路径
            ServletContext servletContext = request.getSession().getServletContext();
            String templatePath = servletContext.getRealPath("template" + File.separator + "report_template.xlsx");
            //获取工作簿，将模板导入内存中
            workbook = new XSSFWorkbook(new FileInputStream(new File(templatePath)));
            XSSFSheet sheet = workbook.getSheetAt(0);
            XSSFRow date4Row = sheet.getRow(2);
            date4Row.getCell(5).setCellValue(reportDate);
            XSSFRow newMemberRow = sheet.getRow(4);
            newMemberRow.getCell(5).setCellValue(todayNewMember);
            newMemberRow.getCell(7).setCellValue(totalMember);
            XSSFRow newMemberRow4WeekAndMonth = sheet.getRow(5);
            newMemberRow4WeekAndMonth.getCell(5).setCellValue(thisWeekNewMember);
            newMemberRow4WeekAndMonth.getCell(7).setCellValue(thisMonthNewMember);
            XSSFRow todayOrderRow = sheet.getRow(7);
            todayOrderRow.getCell(5).setCellValue(todayOrderNumber);
            todayOrderRow.getCell(7).setCellValue(todayVisitsNumber);
            XSSFRow weekOrderRow = sheet.getRow(8);
            weekOrderRow.getCell(5).setCellValue(thisWeekOrderNumber);
            weekOrderRow.getCell(7).setCellValue(thisWeekVisitsNumber);
            XSSFRow monthOrderRow = sheet.getRow(9);
            monthOrderRow.getCell(5).setCellValue(thisMonthOrderNumber);
            monthOrderRow.getCell(7).setCellValue(thisMonthVisitsNumber);
            int rowNum = 12;
            for (Map map : hotSetmeal) {
                XSSFRow hotMealRow = sheet.getRow(rowNum++);
                hotMealRow.getCell(4).setCellValue((String) map.get("name"));
                hotMealRow.getCell(5).setCellValue((Long) map.get("setmeal_count"));
                hotMealRow.getCell(6).setCellValue((String) map.get("proportion"));
            }
            os = response.getOutputStream();
            response.setContentType(servletContext.getMimeType("report_template.xlsx") + ";charset=utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=report.xlsx");
            workbook.write(os);
            os.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (workbook != null) {
                try {
                    workbook.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 导出pdf功能
     *
     * @param request
     * @param response
     */
    @RequestMapping("/exportBusinessReport4PDF")
    public void exportBusinessReport4PDF(HttpServletRequest request, HttpServletResponse response) {
        ServletOutputStream os = null;
        try {
            Map<String, Object> reportData = reportService.getBusinessReportData();
            List<Map> hotSetmeal = (List<Map>) reportData.get("hotSetmeal");
            //获取服务器端绝对路径
            ServletContext servletContext = request.getSession().getServletContext();
            //编译pdf模板并添加数据
            String jrxmlPath = servletContext.getRealPath("template" + File.separator + "health_business3.jrxml");
            String jasperPath = servletContext.getRealPath("template" + File.separator + "health_business3.jasper");
            JasperCompileManager.compileReportToFile(jrxmlPath, jasperPath);
            JasperPrint jasperPrint = JasperFillManager.fillReport(jasperPath, reportData, new JRBeanCollectionDataSource(hotSetmeal));
            //下载功能
            os = response.getOutputStream();
            response.setContentType(servletContext.getMimeType("a.pdf") + ";charset=utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=report.pdf");
            JasperExportManager.exportReportToPdfStream(jasperPrint, os);
            os.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }


}